#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.12"
# dependencies = [
#     "pwntools",
# ]
# ///
import sys
from collections import deque
from pwn import remote


emoji_map = {
    b'\xf0\x9f\x94\xa5': b'#', # 🔥
    b'\xe2\x98\xa0\xef\xb8\x8f': b'#', # ☠️ 
    b'\xf0\x9f\x92\x8e': b'e', # 💎
    b'\xf0\x9f\x94\xa9': b'p', # 🔩
    b'\xf0\x9f\xa4\x96': b's', # 🤖
    b' ': b'',
}

direction_map = {
    'D': (1, 0),
    'U': (-1, 0),
    'L': (0,  -1),
    'R': (0, 1)
}


def solve_maze(data: bytes) -> str:
    for key, value in emoji_map.items():
        data = data.replace(key, value)
    data = data.decode()
    
    path_spaces = []
    for r, line in enumerate(data.splitlines()):
        for c, ch in enumerate(line.strip()):
            if ch in 'spe':
                path_spaces.append((r, c))
            if ch == 's':
                start = (r, c)
            elif ch == 'e':
                end = (r, c)

    assert start is not None
    assert end is not None

    # state = (r, c, path)
    q = deque([(*start, '')])
    visited = set()

    while q:
        r, c, path = q.popleft()
        if (r, c) in visited:
            continue
        visited.add((r, c))

        for move, (dr, dc) in direction_map.items():
            nr, nc = r + dr, c + dc
            if (nr, nc) == end:
                return path + move
            if (nr, nc) in path_spaces:
                q.append((nr, nc, path + move))
    raise ValueError("Ran out of spaces to check")


if len(sys.argv) != 3:
    print(f"usage: {sys.argv[0]} <ip> <port>")
    sys.exit()

r = remote(sys.argv[1], sys.argv[2])
r.recvuntil(b'> ')
r.sendline(b'2')

while True:
    try:
        data = r.recvuntil(b'> ')
    except EOFError:
        break
    solution = solve_maze(data)
    r.sendline(solution.encode())
    results = r.recvuntil(b'\n\n')
    print('\r' + results.decode().strip().replace('\n', ' '), end='')

print()
print(r.recvall().decode())
